local RoomScene = require 'packages.chess-games.xiangqi.core.handler.roomscene'
local control = (require 'packages.chess-games.xiangqi.core.handler.ui_emu')
local PointItem = control.Point
local Xq = require "packages.chess-games.xiangqi"

---@class Xiangqi.ReqPlayChess: RequestHandler
---@field public selected_piece integer? 已选棋子的id
---@field public movable_points integer[] 可行的坐标，为pointId[]，pointId就是y*10+x
local ReqPlayChess = RequestHandler:subclass("Xiangqi.ReqPlayChess")

---@class Xiangqi.ReqPlayChess
---@field public room Xiangqi.RoomBase

function ReqPlayChess:initialize(player, data)
  RequestHandler.initialize(self, player)
  self.scene = RoomScene:new(self)

  self.movable_points = {}
end

function ReqPlayChess:setup()
  self:updateUnselectedPieces()
end

function ReqPlayChess:finish()
  self:clearMovablePoints()
end

function ReqPlayChess:updateUnselectedPieces()
  local scene = self.scene

  for cid, item in pairs(scene:getAllItems("Xiangqi.PieceItem")) do
    if not item.selected then
      local enabled
      if self.player.role == "red" then
        enabled = cid > 0
      else
        enabled = cid < 0
      end

      scene:update("Xiangqi.PieceItem", cid, { enabled = enabled })
    end
  end
end

function ReqPlayChess:selectPiece(id, data)
  local scene = self.scene
  local selected = data.selected
  scene:update("Xiangqi.PieceItem", id, data)

  -- 清除已选，然后若选中，将已选棋子设为这个
  if self.selected_piece then
    scene:update("Xiangqi.PieceItem", self.selected_piece, { selected = false })
    self.selected_piece = nil
  end
  if selected then
    self.selected_piece = id
  end

  if self.selected_piece then
    self:updateMovablePoints()
  else
    self:clearMovablePoints()
    self:updateUnselectedPieces()
  end
end

function ReqPlayChess:clearMovablePoints()
  local scene = self.scene
  for _, id in ipairs(self.movable_points) do
    scene:removeItem("Xiangqi.PointItem", id)
  end
  self.movable_points = {}
end

function ReqPlayChess:updateMovablePoints()
  self:clearMovablePoints()

  if not self.selected_piece then return end

  local scene = self.scene
  local piece = Xq:getPieceById(self.selected_piece)
  local pieceItem = scene:getAllItems("Xiangqi.PieceItem")[self.selected_piece]
  local fromX, fromY = pieceItem.xPos, pieceItem.yPos
  local board = self.room.board

  for y = 1, 10 do
    for x = 1, 9 do
      local id = y * 10 + x
      if piece:canMoveTo(board, fromX, fromY, x, y) and not piece:willBeChecked(board, fromX, fromY, x, y) then
        table.insert(self.movable_points, id)
        local point = PointItem:new(scene, id)
        scene:addItem(point)
      end
    end
  end
end

function ReqPlayChess:moveTo(x, y)
  if not self.selected_piece then return end

  local scene = self.scene
  local pieceItem = scene:getAllItems("Xiangqi.PieceItem")[self.selected_piece]
  local fromX, fromY = pieceItem.xPos, pieceItem.yPos

  local reply = {
    pieceId = self.selected_piece,
    fromX = fromX,
    fromY = fromY,
    x = x,
    y = y,
  }

  if ClientInstance then
    ClientInstance:notifyUI("ReplyToServer", reply)
  else
    return reply
  end
end

function ReqPlayChess:update(elemType, id, action, data)
  if elemType == "Xiangqi.PieceItem" then
    self:selectPiece(id, data)
  elseif elemType == "Xiangqi.PointItem" then
    local x = id % 10
    local y = id // 10
    self:moveTo(x, y)
    return true
  end
end

return ReqPlayChess
